#include "inc/system.h"
#include "inc/print.h"
#include "inc/StorageDevice.h"
#include "inc/Sd2Card.h"
#include "inc/ch375b.h"
#include "inc/FileSystem.h"


#define DS1302_READ 1
#define DS1302_RAM 0x20

void initDisk(StorageDevice* sd, SdVolume** sdvolumes, int* totalVolume){
  int res;
  SdVolume* tempVol = (SdVolume*)malloc(sizeof(SdVolume));
  res = tempVol->init(sd, 0);
  if(res){
    print("found volume 0\r\n");
    sdvolumes[*totalVolume] = tempVol;
    *totalVolume = *totalVolume + 1;
    return;
  }else{
    res = tempVol->init(sd, 1);
    if(res){
      print("found volume 1\r\n");
      sdvolumes[*totalVolume] = tempVol;
      *totalVolume = *totalVolume + 1;
      return;
    }
  }
  mfree(sizeof(SdVolume));
}

int wait(int ms){
    int t0 = IORD(MYTIMER, MYTIMER_32SLOW);
    while(1){
      int tick = IORD(MYTIMER, MYTIMER_32SLOW);
      int diff = tick - t0;
      if(diff>ms){
        break;
      }
    }
}

int main(){
  int val = IORD(DEBUGGER, DEBUGGER_FLG_SYSTEM_VER);
  if(val & 1){
    jmp(0);
    while(1);
    //jmp(32*4);
  }
  //
  
  initMallocIndex();
  stdioInit(62 * 512);
  print("Hello from BIOS 1.0\r\n");
  print("3");
  wait(1000);
  print("2");
  wait(1000);
  print("1");
  wait(1000);
  print("0");
  
  
  SdVolume* sdvolumes[8];
  int totalVolume = 0;
  SdVolume* currVolume;
  int icurrVolume;

  int res;
  {
    int cardidx = 0;
    Sd2Card* sdcard = new Sd2Card();
    res = sdcard->init(cardidx);
    if(res){
      print("found card ");printInt(cardidx);print("\r\n");
      initDisk(sdcard, sdvolumes, &totalVolume);
    }else{
      res = sdcard->init(cardidx);
      print("retry\r\n");
      if(res){
        print("found card ");printInt(cardidx);print("\r\n");
        initDisk(sdcard, sdvolumes, &totalVolume);
      }else{
        res = sdcard->init(cardidx);

        print("card error ");printInt(sdcard->initError);print("\r\n");
      }
    }
  }
  
  {
    CH375b* ch375b = new CH375b();
    res = ch375b->init();
    if(res){
      print("found usb driver ");print("\r\n");
      print("usb driver secCount:");printInt(ch375b->secCount);print("\r\n");
      print("usb driver secSize:");printInt(ch375b->secSize);print("\r\n");
      initDisk(ch375b, sdvolumes, &totalVolume);
    }else{
      print("ch375b error ");printInt(ch375b->initError);print("\r\n");
    }
  }
  
  for(int i=0;i<totalVolume;i++){
    sdvolumes[i]->root = (SdFile*)malloc(sizeof(SdFile));
    res = sdvolumes[i]->root->openRoot(sdvolumes[i]);
    if(res){
      print("found root");printInt(i);print("\r\n");
      sdvolumes[i]->root->dirList(8, 7);
    }else{
      print("root error");printInt(i);print("\r\n");
    }
  }
  currVolume = sdvolumes[0];
  icurrVolume = 0;

  SdFile* file = (SdFile*)malloc(sizeof(SdFile));//at8M~
  
  print("loading boot.bin\r\n");
  wait(1000);

  char* filename = "boot.bin";
  res = file->open(sdvolumes[0]->root, filename, O_READ);
  if(res){
    print("open ok\r\n");
    printInt(file->fileSize_);print("\r\n");
    
    char* data = (char*)0;

    for(int i=0;i<file->fileSize_;i+=512){
      file->read(data+i, 512);
    }

    print("start OS\r\n");
    wait(1000);
    jmp(0);

  }else{
    print("open ng\r\n");
    printInt(file->fileError);print("\r\n");
  }

  
  while(1);
}
